﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Korbit;
using Korbit.Constant;


namespace Korbit.Common
{
    public class PublicExchange
    {
        public const string DATATABLE_BID = "BIDTABLE";
        public const string DATATABLE_ASK = "ASKTABLE";
        public const string DATATABLE_OPENORDER = "OPENORDERTABLE";

        KorbitAccessInfo _AccessInfo;
        
        DataSet _dsInformation;
        DataTable _dtBidTable;
        DataTable _dtAskTable;
        DataTable _dtOpenOrderTable;


        public PublicExchange(KorbitAccessInfo AccesInfo)
        {
            _AccessInfo = AccesInfo;

            initializedDataSet();
        }

        public void initializedDataSet()
        {
            DataColumn dt_col;

            //DataSet 생성
            _dsInformation = new DataSet("Korbit");

            //Bid Table
            _dtBidTable = new DataTable(DATATABLE_BID);

            dt_col = _dtBidTable.Columns.Add();
            dt_col.ColumnName = "BidVolume";
            dt_col.DataType = System.Type.GetType("System.Decimal");

            dt_col = _dtBidTable.Columns.Add();
            dt_col.ColumnName = "BitcoinPrice";
            dt_col.DataType = System.Type.GetType("System.Decimal");

            dt_col = _dtBidTable.Columns.Add();
            dt_col.ColumnName = "AskVolume";
            dt_col.DataType = System.Type.GetType("System.Decimal");

            _dsInformation.Tables.Add(_dtBidTable);


            //Ask Table
            _dtAskTable = new DataTable(DATATABLE_ASK);

            dt_col = _dtAskTable.Columns.Add();
            dt_col.ColumnName = "BidVolume";
            dt_col.DataType = System.Type.GetType("System.Decimal");

            dt_col = _dtAskTable.Columns.Add();
            dt_col.ColumnName = "BitcoinPrice";
            dt_col.DataType = System.Type.GetType("System.Decimal");

            dt_col = _dtAskTable.Columns.Add();
            dt_col.ColumnName = "AskVolume";
            dt_col.DataType = System.Type.GetType("System.Decimal");

            _dsInformation.Tables.Add(_dtAskTable);

            //Order Table
            _dtOpenOrderTable = new DataTable(DATATABLE_OPENORDER);
            dt_col = _dtOpenOrderTable.Columns.Add();
            dt_col.ColumnName = "timestamp";
            dt_col.DataType = System.Type.GetType("System.TimeSpan");

            dt_col = _dtOpenOrderTable.Columns.Add();
            dt_col.ColumnName = "OrderID";
            dt_col.DataType = System.Type.GetType("System.Decimal");

            dt_col = _dtOpenOrderTable.Columns.Add();
            dt_col.ColumnName = "OrderType";
            dt_col.DataType = System.Type.GetType("System.String");

            dt_col = _dtOpenOrderTable.Columns.Add();
            dt_col.ColumnName = "BTCPrice";
            dt_col.DataType = System.Type.GetType("System.Decimal");

            dt_col = _dtOpenOrderTable.Columns.Add();
            dt_col.ColumnName = "BTCVolume";
            dt_col.DataType = System.Type.GetType("System.Decimal");

            dt_col = _dtOpenOrderTable.Columns.Add();
            dt_col.ColumnName = "OpenBtCVolume";
            dt_col.DataType = System.Type.GetType("System.Decimal");
            
            _dsInformation.Tables.Add(_dtOpenOrderTable);

        }

        public void RetreivedContract()
        {
            string strData;

            strData = Communication.GetRequestData(_AccessInfo.GetBaseURL() + KorbitURL.URL_ORDER_BOOKS, "");

            if (strData.Length == 0)
                return;
            
            SetContratData(strData);
            
        }

        private void SetContratData(string strData)
        {
            if(strData.Length == 0)
                return;

            //JSON으로 변경
            JObject objData = JObject.Parse(strData);


            // 매도 테이블 삽입
            JArray oItems = JArray.Parse(objData["asks"].ToString());
            _dtAskTable.Rows.Clear();
            foreach (JToken oItem in oItems)
            {
                try
                {
                    DataRow row = _dtAskTable.NewRow();
                    row["BitcoinPrice"] = oItem[0].ToString();
                    row["AskVolume"] = oItem[1].ToString();
                    _dtAskTable.Rows.Add(row);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }

            }

            // 매수 테이블 삽입
            oItems = JArray.Parse(objData["bids"].ToString());
            _dtBidTable.Rows.Clear();
            foreach (JToken oItem in oItems)
            {
                try
                {
                    DataRow row = _dtBidTable.NewRow();
                    row["BitcoinPrice"] = oItem[0].ToString();
                    row["BidVolume"] = oItem[1].ToString();
                    _dtBidTable.Rows.Add(row);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }

            }

        }

        public DataTable GetAskTable()
        {
            return _dtAskTable;
        }

        public DataTable GetBidTable()
        {
            return _dtBidTable;
        }

        public void RetreivedOpenOrder()
        {
            string strData;
            string strURL;
            string strParameter;

            Dictionary<string, string> dicParameter = _AccessInfo.GetURLParameterAccessKey();
            dicParameter.Add("offset", "0");
            dicParameter.Add("limit", "100");


            strURL = _AccessInfo.GetBaseURL() + KorbitURL.URL_ORDER_OPEN;
            strParameter = CommonFunction.ConvertURLParameter(dicParameter);

            strURL = strURL + "?" + strParameter;

            strData = Communication.GetRequestData(strURL, "");

            if (strData.Length == 0)
                return;

            SetOpenOrder(strData);

        }

        private void SetOpenOrder(string strData)
        {
            if (strData.Length == 0)
                return;

            JArray objData = JArray.Parse(strData);
            _dtOpenOrderTable.Rows.Clear();
            foreach (JToken oItem in objData)
            {
                DataRow dr = _dtOpenOrderTable.NewRow();
                dr["timestamp"] = new TimeSpan(Int64.Parse(oItem["timestamp"].ToString()));
                dr["OrderID"] = oItem["id"].ToString();

                if (oItem["id"].ToString() == "ask")
                {
                    dr["OrderType"] = "매도";
                }
                else
                {
                    dr["OrderType"] = "매수";
                }

                JToken oSubItem = oItem["price"];
                dr["BTCPrice"] = Double.Parse(oSubItem["value"].ToString());

                oSubItem = oItem["total"];
                dr["BTCVolume"] = Double.Parse(oSubItem["value"].ToString());

                oSubItem = oItem["open"];
                dr["OpenBtCVolume"] = Double.Parse(oSubItem["value"].ToString());

                _dtOpenOrderTable.Rows.Add(dr);                
            }
        }

        public DataTable GetOpenOrderTable()
        {
            return _dtOpenOrderTable;
        }

    }
}
